package com.socialrss.instagramkit;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;

//import javax.net.ssl.HttpsURLConnection;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.os.AsyncTask;
import android.util.Log;

import com.socialrss.accounts.AbstractHolder;
import com.socialrss.accounts.AccountOwner;
import com.socialrss.accounts.FollowedPerson;
import com.socialrss.accounts.InstagramNotification;
import com.socialrss.accounts.InstagramUser;
import com.socialrss.constants.SocialNetworkNames;
import com.socialrss.constants.SocialNetworkNames.SocialNetKeys;
import com.socialrss.utils.SocialRssModel;

public class InstagramUtils {
	private static InstagramUtils instagramutils;

	private String accessToken = null;
	
	public String getAccessToken() {
		return accessToken;
	}
	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}
	private InstagramUtils(){
		AccountOwner own = SocialRssModel.Instance(null).getAccessTokenOfSocialNet(SocialNetKeys.ins.toString());
		this.accessToken = own.getAccessToken();
	}
	public static InstagramUtils Instance(){
		if(instagramutils == null){
			instagramutils = new InstagramUtils();
		}
		return instagramutils;
	}
	public InstagramUser getUserInfo(int  userid){
		RetrieveUserInfo userinf = new RetrieveUserInfo();
		userinf.execute(userid);
		InstagramUser insTemp = null;
		try {
			insTemp = userinf.get();
		} catch (Exception e) {
			Log.e(InstagramConstants.LOG_ERROR, "RetrievetUserInfo fails!");
			e.printStackTrace();
		} 
		
		return insTemp;
	}
	public void lookForNotifications(){
		String postid = SocialRssModel.Instance(null).getLastPostId(SocialNetworkNames.INSTAGRAM);
		String strUrl;
		if(postid != null){
			strUrl = InstagramConstants.APIURL + "/users/self/feed?min_id=" + postid + "&access_token=" + accessToken;
		}
		else{
			strUrl = InstagramConstants.APIURL + "/users/self/feed?count=" + 1 + "&access_token=" + accessToken;
		}
		try{
			URL url = new URL(strUrl);
	
			Log.d(InstagramConstants.LOG_REQUEST, "Opening URL " + url.toString());
			HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection() ;
			urlConnection.setRequestMethod("GET");
			urlConnection.setDoInput(true);
			//urlConnection.setDoOutput(true);
			urlConnection.connect();
			String response = streamToString(urlConnection.getInputStream());
			System.out.println(response);
			JSONObject jsonObj = (JSONObject) new JSONTokener(response).nextValue();
					
			//just get ids of each
			//number of ids will be equal to count
			JSONArray myar = jsonObj.getJSONArray("data");
			LinkedHashMap <Integer, AbstractHolder> instagramCons = SocialRssModel.Instance(null).getConnectionsOfSocialNetwork(SocialNetworkNames.INSTAGRAM);
			if(myar.length()>0){
				postid = myar.getJSONObject(0).getString("id");
				for (int i = 0; i < myar.length(); i++) {
					JSONObject tempPost = jsonObj.getJSONArray("data").getJSONObject(i);
					String userid = tempPost.getJSONObject("user").getString("id");
					FollowedPerson myConn = (FollowedPerson) instagramCons.get(userid);
					if(myConn!=null){				
						if(myConn.isTurnedOn()){					//this means a connection who is subscribed, has post(s).		
							InstagramNotification tempNot = new InstagramNotification();
							tempNot.setLink(tempPost.getString("link"));
							tempNot.setDate(tempPost.getInt("created_time"));
							tempNot.setTextContent(" has posted new photo.");
							tempNot.setImageContentLink(tempPost.getJSONObject("images").getJSONObject("thumbnail").getString("url"));
							myConn.addNewNotification(tempNot);		//add this notification into followed person
						}
					}
				}
				SocialRssModel.Instance(null).setLastPostId(SocialNetworkNames.INSTAGRAM, postid);		//store id of last post
			}
			
		}
		catch(Exception e){
			e.printStackTrace();
			Log.e(InstagramConstants.LOG_ERROR, "While controlling posts from min_id : " + postid + "\n" + e.toString());
		}
		
	}
	/**
	 * User is owner of account. Returned list will be users who the owner follows.
	 * Count is number of userinfo to retrieve. From top of the list, this number of userinfo is retrieved.
	 * @param user
	 * @param count
	 * @return
	 */
	public InstagramUser[] get_Ids_Of_AllFollows(final InstagramUser user, final int count){
		if(count < 1){
			return new InstagramUser[0];
		}
		final InstagramUser[] userlist = new InstagramUser[count];
		
		Thread tempth = new Thread(){
			@Override
			public void run(){
				String userid = "";
				if(user.getId() == -1){
					userid = "self";
				}
				else{
					userid += user.getId();
				}
				String strUrl = InstagramConstants.APIURL + "/users/" + userid + "/follows" + "/?access_token=" + accessToken;
	    		try{
	    			URL url = new URL(strUrl);
	    	
	    			Log.d(InstagramConstants.LOG_REQUEST, "Opening URL " + url.toString());
	    			HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection() ;
	    			urlConnection.setRequestMethod("GET");
	    			urlConnection.setDoInput(true);
	    			//urlConnection.setDoOutput(true);
	    			urlConnection.connect();
	    			String response = streamToString(urlConnection.getInputStream());
	    			System.out.println(response);
	    			JSONObject jsonObj = (JSONObject) new JSONTokener(response).nextValue();
	    					
	    			//just get ids of each
	    			//number of ids will be equal to count
	    			for (int i = 0; i < count; i++) {
	    				userlist[i] = new InstagramUser(0);
	    				JSONObject temp = jsonObj.getJSONArray("data").getJSONObject(i);
	    				userlist[i].setId(Integer.parseInt(temp.getString("id")));
	    				userlist[i].setName(temp.getString("username"));
	    				//userlist[i].setFullName(jsonObj.getJSONArray("data").getJSONObject(i).getString("full_name"));
					}
	    		}
	    		catch(Exception e){
	    			e.printStackTrace();
	    			Log.e(InstagramConstants.LOG_ERROR, "While requesting : " + strUrl + " " + e.toString());
	    		}
			}
		};
		tempth.start();
		try {
			tempth.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return userlist;
	}
//	private InstagramUser fetchFromJason(JSONObject user){
//		InstagramUser temp = new InstagramUser(id);
//	}
	protected String streamToString(InputStream is) throws IOException {
		String str = "";

		if (is != null) {
			StringBuilder sb = new StringBuilder();
			String line;

			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(is));

				while ((line = reader.readLine()) != null) {
					sb.append(line);
				}

				reader.close();
			} finally {
				is.close();
			}

			str = sb.toString();
		}

		return str;
	}
	
	private class RetrieveUserInfo extends AsyncTask<Integer, Void, InstagramUser> {


		@Override
		protected InstagramUser doInBackground(Integer... params) {
//			String userid = "";
//			if(params[0] == -1){
//				userid = "self";
//			}
//			else{
//				userid += params[0];
//			}
        	String strUrl = InstagramConstants.APIURL + "/users/" + params[0] + "/?access_token=" + accessToken;
        	InstagramUser tempInstagramUser = new InstagramUser(params[0]);	
        	JSONObject jsonObj=null;
    		try{
    			URL url = new URL(strUrl);
    	
    			Log.d(InstagramConstants.LOG_REQUEST, "Opening URL " + url.toString());
    			HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection() ;
    			urlConnection.setRequestMethod("GET");
    			urlConnection.setDoInput(true);
    			//urlConnection.setDoOutput(true);
    			urlConnection.connect();
    			String response = streamToString(urlConnection.getInputStream());
    			System.out.println(response);
    			jsonObj = (JSONObject) new JSONTokener(response).nextValue();
    					
//    			
    			tempInstagramUser.setId(params[0]);
    			tempInstagramUser.setName(jsonObj.getJSONObject("data").getString("username"));
    			tempInstagramUser.setFullName(jsonObj.getJSONObject("data").getString("full_name"));
    			tempInstagramUser.setFollows( jsonObj.getJSONObject("data").getJSONObject("counts").getInt("follows"));
    			tempInstagramUser.setFollowed_by( jsonObj.getJSONObject("data").getJSONObject("counts").getInt("followed_by") );
    			tempInstagramUser.setMedia( jsonObj.getJSONObject("data").getJSONObject("counts").getInt("media") );
    		}
    		catch(Exception e){
    			e.printStackTrace();
    			Log.e(InstagramConstants.LOG_ERROR, "While requesting : " + strUrl + " " + e.toString());
    		}
			return tempInstagramUser;
        }
     }
}
